use crate::lexer::Lexer;
use crate::parser::Parser;
use crate::evaluator::eval;
use std::io::{self, BufRead, Write};

const PROMPT: &str = ">> ";

// 启动 REPL 循环
pub fn start<R: io::Read, W: io::Write>(reader: R, mut writer: W) -> io::Result<()> {
    let mut buf_reader = io::BufReader::new(reader);

    loop {
        // 打印提示符
        write!(writer, "{}", PROMPT)?;
        writer.flush()?; // 确保提示符立即显示

        let mut line = String::new();
        let read_bytes = buf_reader.read_line(&mut line)?;

        // 如果读到文件末尾 (EOF)，则退出循环
        if read_bytes == 0 {
            writeln!(writer, "\nExiting REPL.")?;
            return Ok(());
        }

        let lexer = Lexer::new(line);
        let mut parser = Parser::new(lexer);
        let program = parser.parse_program();

        // 检查是否有解析错误
        if !parser.get_errors().is_empty() {
            print_parser_errors(&mut writer, &parser.get_errors())?;
            continue;
        }
        let evaluated = eval(&program);
        // 打印程序
        
        writeln!(writer, "{}", evaluated.as_ref().inspect())?;
        writeln!(writer , "\n")?;
        // if let Some(o) =evaluated{
        //     writeln!(writer, "{}", o.inspect())?;
        //     writeln!(writer , "\n")?;
        //     // writeln!(writer, "{}", program.to_string())?;
        // }
        // 打印程序
        // writeln!(writer, "{}", program.to_string())?;
    }
}

// 打印解析器错误
fn print_parser_errors<W: io::Write>(writer: &mut W, errors: &[String]) -> io::Result<()> {
    writeln!(writer, "  Woops! We ran into some monkey business here!")?;
    writeln!(writer, "   parser errors:")?;
    for msg in errors {
        writeln!(writer, "\t{}", msg)?;
    }
    Ok(())
}